/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Source;

import java.io.BufferedReader;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import net.jxta.document.AdvertisementFactory;
import net.jxta.id.IDFactory;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.socket.JxtaServerSocket;

/**
 *
 * @author Miguel
 */
public class PeerServerSocket implements Runnable {

    private transient PeerGroup netPeerGroup = null;
    public final static String SOCKETIDSTR = "urn:jxta:uuid-59616261646162614E5047205032503393B5C2F6CA7A41FBB0F890173088E79404";
    public static final long TAM_PAQUETES = 512;

    public PeerServerSocket(PeerGroup netPeerGroup) {
        this.netPeerGroup = netPeerGroup;
    }

    public static PipeAdvertisement createSocketAdvertisement() {
        PipeID socketID = null;

        try {
            socketID = (PipeID) IDFactory.fromURI(new URI(SOCKETIDSTR));
        } catch (URISyntaxException use) {
            use.printStackTrace();
        }
        PipeAdvertisement advertisement = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());

        advertisement.setPipeID(socketID);
        advertisement.setType(PipeService.UnicastType);
        advertisement.setName("Peer to peer socket");
        System.out.println("Saliendo del socket server");
        return advertisement;
    }

    public void run() {
        System.out.println("Starting ServerSocket");
        JxtaServerSocket serverSocket = null;
        try {
            serverSocket = new JxtaServerSocket(netPeerGroup, createSocketAdvertisement(), 10);
            serverSocket.setSoTimeout(0);
        } catch (IOException e) {
            System.out.println("failed to create a server socket");
            e.printStackTrace();
            System.exit(-1);
        }

        while (true) {
            try {
                System.out.println("Waiting for connections");
                Socket socket = serverSocket.accept();
                if (socket != null) {
                    System.out.println("New socket connection accepted");
                    Thread thread = new Thread(new ConnectionHandler(socket), "Connection Handler Thread");
                    thread.start();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private class ConnectionHandler implements Runnable {

        Socket socket = null;

        ConnectionHandler(Socket socket) {
            this.socket = socket;
        }

        /**
         * Sends data over socket
         *
         * @param socket the socket
         */
        private void sendAndReceiveData(Socket socket) {
            try {
                long start = System.currentTimeMillis();

                // get the socket output stream
                OutputStream out = socket.getOutputStream();
                // get the socket input stream
                InputStream in = socket.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                String mensaje = br.readLine();
                String nombreArchivo = mensaje.split(";")[1];
                File archivoAMandar = new File("../temp/Compartidos/", nombreArchivo);
                     if(archivoAMandar.exists()) {
                            FileInputStream fis = new FileInputStream(archivoAMandar);
                            long tamArchivo = archivoAMandar.length();
                            if (tamArchivo < TAM_PAQUETES) {
                                byte[] menor = new byte[(int) tamArchivo];
                                fis.read(menor);
                                out.write(menor);
                            } else {

                                long numeroPaquetes = tamArchivo / TAM_PAQUETES;
                                for (int i = 0; i < numeroPaquetes; i++) {
                                    byte[] paq = new byte[(int) TAM_PAQUETES];
                                    fis.read(paq);
                                    out.write(paq);
                                    //System.out.println("iteracion:" + i);
                                }
                                long loQuefalta = archivoAMandar.length() - (numeroPaquetes * TAM_PAQUETES);
                                if (loQuefalta > 0) {
                                    byte[] falta = new byte[(int) loQuefalta];
                                    fis.read(falta);
                                    out.write(falta);
                                }
                            }
                            fis.close();
                            socket.close();
                            System.out.println("Conexión cerrada");
                }
            } catch (Exception ie) {
                ie.printStackTrace();
            }
        }

        public void run() {
            sendAndReceiveData(socket);
        }
    }
}
